using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
using OpenIddict.Validation.AspNetCore;
using System;
using System.IO;
using System.Text.Json;
using System.Text.Json.Serialization;
using Volo.Abp;
using Volo.Abp.Account.Web;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.AntiForgery;
using Volo.Abp.AspNetCore.Mvc.Libs;
using Volo.Abp.AspNetCore.Mvc.Localization;
using Volo.Abp.AspNetCore.Mvc.UI;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared;
using Volo.Abp.AspNetCore.Serilog;
using Volo.Abp.Autofac;
using Volo.Abp.AutoMapper;
using Volo.Abp.BlobStoring;
using Volo.Abp.BlobStoring.Aliyun;
using Volo.Abp.EventBus.RabbitMq;
using Volo.Abp.FeatureManagement;
using Volo.Abp.Identity.Web;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.OpenIddict;
using Volo.Abp.PermissionManagement.Web;
using Volo.Abp.RabbitMQ;
using Volo.Abp.Security.Claims;
using Volo.Abp.SettingManagement.Web;
using Volo.Abp.Swashbuckle;
using Volo.Abp.TenantManagement.Web;
using Volo.Abp.UI;
using Volo.Abp.UI.Navigation;
using Volo.Abp.UI.Navigation.Urls;
using Volo.Abp.VirtualFileSystem;
using WMSSystem.EntityFrameworkCore;
using WMSSystem.JWT;
using WMSSystem.Localization;
using WMSSystem.MultiTenancy;
using WMSSystem.Web.Hubs;
using WMSSystem.Web.Menus;
using WMSSystem.Web.Services;
using WMSSystem.YJ.DTO.Input;
using WMSSystem.YSL;
using WMSSystem.YSL.Dto.JWT;
using WMSSystem.YSL.Interfance;


namespace WMSSystem.Web;

[DependsOn(
    typeof(WMSSystemHttpApiModule),
    typeof(WMSSystemApplicationModule),
    typeof(WMSSystemEntityFrameworkCoreModule),
    typeof(AbpAutofacModule),
    typeof(AbpIdentityWebModule),
    typeof(AbpSettingManagementWebModule),
    typeof(AbpAccountWebOpenIddictModule),
    typeof(AbpAspNetCoreMvcUiLeptonXLiteThemeModule),
    typeof(AbpTenantManagementWebModule),
    typeof(AbpAspNetCoreSerilogModule),
    typeof(AbpSwashbuckleModule)
    )]
public class WMSSystemWebModule : AbpModule
{
    //private readonly IConfiguration _configuration;

    //public WMSSystemWebModule(IConfiguration configuration)
    //{
    //    _configuration = configuration;
    //}
    //public WMSSystemWebModule()
    //{
    //    // ������캯���ᱻABP���ʹ��
    //}

    public override void PreConfigureServices(ServiceConfigurationContext context)
    {
        var hostingEnvironment = context.Services.GetHostingEnvironment();
        var configuration = context.Services.GetConfiguration();

        context.Services.PreConfigure<AbpMvcDataAnnotationsLocalizationOptions>(options =>
        {
            options.AddAssemblyResource(
                typeof(WMSSystemResource),
                typeof(WMSSystemDomainModule).Assembly,
                typeof(WMSSystemDomainSharedModule).Assembly,
                typeof(WMSSystemApplicationModule).Assembly,
                typeof(WMSSystemApplicationContractsModule).Assembly,
                typeof(WMSSystemWebModule).Assembly
            );
        });

        PreConfigure<OpenIddictBuilder>(builder =>
        {
            builder.AddValidation(options =>
            {
                options.AddAudiences("WMSSystem");
                options.UseLocalServer();
                options.UseAspNetCore();
            });
        });

        if (!hostingEnvironment.IsDevelopment())
        {
            //PreConfigure<AbpOpenIddictAspNetCoreOptions>(options =>
            //{
            //    options.AddDevelopmentEncryptionAndSigningCertificate = false;
            //});

            //PreConfigure<OpenIddictServerBuilder>(serverBuilder =>
            //{
            //    serverBuilder.AddProductionEncryptionAndSigningCertificate("openiddict.pfx", "b5c1dabc-5877-44ae-a504-948e457240e3");
            //});
        }
    }

    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        var hostingEnvironment = context.Services.GetHostingEnvironment();
        var configuration = context.Services.GetConfiguration();

        Configure<AbpAntiForgeryOptions>(options =>
        {
            options.AutoValidate = false;
        });
        Configure<AbpMvcLibsOptions>(options =>
        options.CheckLibs = false
      );
        // 添加SignalR服务
        context.Services.AddSignalR();
        context.Services.AddHostedService<RealTimeStatisticsPushService>();
        // 添加后台服务
        context.Services.AddScoped<IRealTimeStatisticsService, RealTimeStatisticsService>();

        // 配置WorkflowCore
        context.Services.AddWorkflow();

        // 配置JWT设置
        context.Services.Configure<JwtSettings>(configuration.GetSection("JWT"));

        // 注册JWT服务
        context.Services.AddTransient<IJwtService, JwtService>();
        //允许跨域
        context.Services.AddCors(options =>
        {
            options.AddPolicy("AllowAll", policy =>
            {
                policy.SetIsOriginAllowed(_ => true) // 允许所有来源
                      .AllowAnyMethod()
                      .AllowAnyHeader()
                      .AllowCredentials();
            });
        });
        // 配置七牛云选项
        context.Services.Configure<QiniuOptions>(options =>
        {
            options.AccessKey = configuration["Qny:qiniuyunAK"] ?? configuration["Qny:AccessKey"];
            options.SecretKey = configuration["Qny:qiniuyunSK"] ?? configuration["Qny:SecretKey"];
            options.Bucket = configuration["Qny:qiniuyunBucket"] ?? configuration["Qny:Bucket"];
            options.Domain = configuration["Qny:prefixPath"] ?? configuration["Qny:Domain"];
        });

        //Configure<AbpBlobStoringOptions>(options =>
        //{
        //    options.Containers.ConfigureDefault(container =>
        //    {
        //        container.UseAliyun(aliyun =>
        //        {
        //            aliyun.AccessKeyId = configuration["BlobStoring:Aliyun:AccessKeyId"];
        //            aliyun.AccessKeySecret = configuration["BlobStoring:Aliyun:AccessKeySecret"];
        //            aliyun.Endpoint = configuration["BlobStoring:Aliyun:Endpoint"];
        //            aliyun.BucketName = configuration["BlobStoring:Aliyun:ContainerName"];
        //        });
        //    });
        //});

        Configure<AbpRabbitMqOptions>(options =>
        {
            options.Connections.Default.UserName = "admin";
            options.Connections.Default.Password = "123456789";
            options.Connections.Default.HostName = "121.199.31.45";
            options.Connections.Default.Port = 5672;
        });
        ConfigureAuthentication(context);
        ConfigureUrls(configuration);
        ConfigureBundles();
        ConfigureAutoMapper();
        ConfigureVirtualFileSystem(hostingEnvironment);
        ConfigureNavigationServices();
        ConfigureAutoApiControllers();
        ConfigureSwaggerServices(context.Services);

        //// 配置JSON序列化选项
        //context.Services.Configure<AbpAspNetCoreMvcOptions>(options =>
        //{
        //    options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles;
        //    options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
        //});


    }


    
    private void ConfigureAuthentication(ServiceConfigurationContext context)
    {
        context.Services.ForwardIdentityAuthenticationForBearer(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme);
        context.Services.Configure<AbpClaimsPrincipalFactoryOptions>(options =>
        {
            options.IsDynamicClaimsEnabled = true;
        });
    }

    private void ConfigureUrls(IConfiguration configuration)
    {
        Configure<AppUrlOptions>(options =>
        {
            options.Applications["MVC"].RootUrl = configuration["App:SelfUrl"];
        });
    }

    private void ConfigureBundles()
    {
        Configure<AbpBundlingOptions>(options =>
        {
            options.StyleBundles.Configure(
                LeptonXLiteThemeBundles.Styles.Global,
                bundle =>
                {
                    bundle.AddFiles("/global-styles.css");
                }
            );
        });
    }

    private void ConfigureAutoMapper()
    {
        Configure<AbpAutoMapperOptions>(options =>
        {
            options.AddMaps<WMSSystemWebModule>();
        });
    }

    private void ConfigureVirtualFileSystem(IWebHostEnvironment hostingEnvironment)
    {
        if (hostingEnvironment.IsDevelopment())
        {
            Configure<AbpVirtualFileSystemOptions>(options =>
            {
                options.FileSets.ReplaceEmbeddedByPhysical<WMSSystemDomainSharedModule>(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}WMSSystem.Domain.Shared"));
                options.FileSets.ReplaceEmbeddedByPhysical<WMSSystemDomainModule>(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}WMSSystem.Domain"));
                options.FileSets.ReplaceEmbeddedByPhysical<WMSSystemApplicationContractsModule>(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}WMSSystem.Application.Contracts"));
                options.FileSets.ReplaceEmbeddedByPhysical<WMSSystemApplicationModule>(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}WMSSystem.Application"));
                options.FileSets.ReplaceEmbeddedByPhysical<WMSSystemWebModule>(hostingEnvironment.ContentRootPath);
            });
        }
    }

    private void ConfigureNavigationServices()
    {
        Configure<AbpNavigationOptions>(options =>
        {
            options.MenuContributors.Add(new WMSSystemMenuContributor());
        });
    }

    private void ConfigureAutoApiControllers()
    {
        Configure<AbpAspNetCoreMvcOptions>(options =>
        {
            options.ConventionalControllers.Create(typeof(WMSSystemApplicationModule).Assembly);
        });
    }

    private void ConfigureSwaggerServices(IServiceCollection services)
    {
        services.AddAbpSwaggerGen(
             //options =>
             //{
             //    options.SwaggerDoc("v1", new OpenApiInfo { Title = "WMSSystem API", Version = "v1" });
             //    options.DocInclusionPredicate((docName, description) => true);
             //    options.CustomSchemaIds(type => type.FullName);
             //}
             options =>
             {
                 options.SwaggerDoc("v1", new OpenApiInfo { Title = "WMSSystem API", Version = "v1" });
                 options.DocInclusionPredicate((docName, description) => true);
                 options.CustomSchemaIds(type => type.FullName);

                 // ���� Application ��� XML ע��
                 var xmlPath = Path.Combine(AppContext.BaseDirectory, "WMSSystem.Application.xml");
                 if (File.Exists(xmlPath))
                 {
                     options.OperationFilter<AppServiceCommentOperationFilter>(xmlPath);
                 }
             }
        );
    }

    public override void OnApplicationInitialization(ApplicationInitializationContext context)
    {
        var app = context.GetApplicationBuilder();
        var env = context.GetEnvironment();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseAbpRequestLocalization();

        if (!env.IsDevelopment())
        {
            app.UseErrorPage();
        }

        app.UseCorrelationId();
        app.UseStaticFiles(); // 添加静态文件中间件
        app.MapAbpStaticAssets();
        //app.UseCors(x => x.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());//跨域
        app.UseCors("AllowAll");
        app.UseRouting();
        app.UseAuthentication();
        app.UseAbpOpenIddictValidation();

        if (MultiTenancyConsts.IsEnabled)
        {
            app.UseMultiTenancy();
        }

        app.UseUnitOfWork();
        app.UseDynamicClaims();
        app.UseAuthorization();
        // 配置SignalR Hub路由
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapHub<RealTimeStatisticsHub>("/hubs/realTimeStatistics");
        });
        //app.UseEndpoints(endpoints =>
        //{
        //    endpoints.MapHub<RealTimeStatisticsHub>("/realtimeStatisticsHub");
        //    endpoints.MapControllers();
        //});
        app.UseSwagger();
        app.UseAbpSwaggerUI(options =>
        {
            options.SwaggerEndpoint("/swagger/v1/swagger.json", "WMSSystem API");
        });

        app.UseAuditing();
        app.UseAbpSerilogEnrichers();
        app.UseConfiguredEndpoints();
        
        // 启动WorkflowCore
        var workflowHost = context.ServiceProvider.GetService<WorkflowCore.Interface.IWorkflowHost>();
        if (workflowHost != null)
        {
            workflowHost.Start();
        }
    }
}
